#include <iostream>
#include <fstream>
#include <string.h>
#include <fcntl.h>
#include <sys/file.h>
#include <signal.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <iomanip>
#include <sstream>
#include <cinttypes>
#include "ptp.h"

// 将数据写入文件
void write_to_syncfile(const SyncInfo &syncInfo, const char *filename)
{
    // 打开文件
    int fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644);
    if (fd == -1)
    {
        std::cerr << "无法打开文件" << std::endl;
        return;
    }

    // 加锁
    if (flock(fd, LOCK_EX) == -1)
    {
        std::cerr << "无法加锁" << std::endl;
        close(fd);
        return;
    }
    uint32_t Originseconds = static_cast<uint32_t>(syncInfo.PreciseOriginTimestamp >> 32);
    uint32_t Originnanoseconds = static_cast<uint32_t>(syncInfo.PreciseOriginTimestamp & 0xFFFFFFFF);
    uint32_t Recvseconds = static_cast<uint32_t>(syncInfo.RecvTimestamp >> 32);
    uint32_t Recvnanoseconds = static_cast<uint32_t>(syncInfo.RecvTimestamp & 0xFFFFFFFF);
    // 禁用中断
    // block_interrupts();
    char buffer[1024];
    snprintf(buffer, sizeof(buffer),
             "<Sync_Info>\n"
             "SequenceID: %" PRIu16 "\n"
             "PreciseOriginTimestamp: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "CorrectionField: %" PRId64 "\n"
             "RecvTimestamp: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "GMRateRatio: %.10f\n"
             "NeighborRateRatio: %.10f\n"
             "CumulativeScaledRateOffset: %" PRId64 "\n"
             "tickLength: %.10f\n"
             "offset: %" PRId32 "\n"
             "\n",
             syncInfo.SequenceID,
             Originseconds, Originnanoseconds,
             syncInfo.CorrectionField,
             Recvseconds, Recvnanoseconds,
             syncInfo.GMRateRatio,
             syncInfo.NeighborRateRatio,
             syncInfo.CumulativeScaledRateOffset,
             syncInfo.tickLength,
             syncInfo.offset);

    // 写入数据
    ssize_t written = write(fd, buffer, strlen(buffer));
    if (written == -1)
    {
        std::cerr << "写入文件时出错: " << filename << std::endl;
    }

    // 解锁
    if (flock(fd, LOCK_UN) == -1)
    {
        std::cerr << "无法解锁文件: " << filename << std::endl;
    }

    // 关闭文件
    close(fd);
}

// 将数据写入文件
void write_to_delayfile(const LinkdelayInfo &linkInfo, const char *filename)
{
    // 打开文件
    int fd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644);
    if (fd == -1)
    {
        std::cerr << "无法打开文件" << std::endl;
        return;
    }
    // 加锁
    if (flock(fd, LOCK_EX) == -1)
    {
        std::cerr << "无法加锁" << std::endl;
        close(fd);
        return;
    }
    // 提取并输出 t1 的秒和纳秒部分
    uint32_t t1_seconds = static_cast<uint32_t>(linkInfo.t1 >> 32);
    uint32_t t1_nanoseconds = static_cast<uint32_t>(linkInfo.t1 & 0xFFFFFFFF);

    // 提取并输出 t2 的秒和纳秒部分
    uint32_t t2_seconds = static_cast<uint32_t>(linkInfo.t2 >> 32);
    uint32_t t2_nanoseconds = static_cast<uint32_t>(linkInfo.t2 & 0xFFFFFFFF);

    // 提取并输出 t3 的秒和纳秒部分
    uint32_t t3_seconds = static_cast<uint32_t>(linkInfo.t3 >> 32);
    uint32_t t3_nanoseconds = static_cast<uint32_t>(linkInfo.t3 & 0xFFFFFFFF);

    // 提取并输出 t4 的秒和纳秒部分
    uint32_t t4_seconds = static_cast<uint32_t>(linkInfo.t4 >> 32);
    uint32_t t4_nanoseconds = static_cast<uint32_t>(linkInfo.t4 & 0xFFFFFFFF);

    // 提取并输出 last_t1 的秒和纳秒部分
    uint32_t last_t1_seconds = static_cast<uint32_t>(linkInfo.last_t1 >> 32);
    uint32_t last_t1_nanoseconds = static_cast<uint32_t>(linkInfo.last_t1 & 0xFFFFFFFF);

    // 提取并输出 last_t2 的秒和纳秒部分
    uint32_t last_t2_seconds = static_cast<uint32_t>(linkInfo.last_t2 >> 32);
    uint32_t last_t2_nanoseconds = static_cast<uint32_t>(linkInfo.last_t2 & 0xFFFFFFFF);

    // 提取并输出 last_t3 的秒和纳秒部分
    uint32_t last_t3_seconds = static_cast<uint32_t>(linkInfo.last_t3 >> 32);
    uint32_t last_t3_nanoseconds = static_cast<uint32_t>(linkInfo.last_t3 & 0xFFFFFFFF);

    // 提取并输出 last_t4 的秒和纳秒部分
    uint32_t last_t4_seconds = static_cast<uint32_t>(linkInfo.last_t4 >> 32);
    uint32_t last_t4_nanoseconds = static_cast<uint32_t>(linkInfo.last_t4 & 0xFFFFFFFF);

    char buffer[1024];
    snprintf(buffer, sizeof(buffer),
             "<Linkdelay_Info>\n"
             "SequenceID: %" PRIu16 "\n"
             "PortID: %" PRIu16 "\n"
             "t1: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "t2: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "t3: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "t4: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "last_t1: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "last_t2: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "last_t3: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "last_t4: seconds: %" PRIu32 ", nanoseconds: %" PRIu32 " \n"
             "Linkdelay: %" PRIu64 "\n"
             "NeighborRateRatio: %.10f\n"
             "\n",
             linkInfo.sequenceid,
             linkInfo.PortID,
             t1_seconds,
             t1_nanoseconds,
             t2_seconds, t2_nanoseconds,
             t3_seconds, t3_nanoseconds,
             t4_seconds, t4_nanoseconds,
             last_t1_seconds, last_t1_nanoseconds,
             last_t2_seconds, last_t2_nanoseconds,
             last_t3_seconds, last_t3_nanoseconds,
             last_t4_seconds, last_t4_nanoseconds,
             linkInfo.Linkdelay,
             linkInfo.NeighborRateRatio);

    // 写入数据
    ssize_t written = write(fd, buffer, strlen(buffer));
    if (written == -1)
    {
        std::cerr << "写入文件时出错: " << filename << std::endl;
    }

    // 解锁
    if (flock(fd, LOCK_UN) == -1)
    {
        std::cerr << "无法解锁文件: " << filename << std::endl;
    }

    // 关闭文件
    close(fd);
}
